package org.jaaksi.commondemo;

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import ma.MAActivity;

@Zujie(name = "MainActivity") public class MainActivity extends AppCompatActivity {
  private Handler mMainHandler = new Handler() {
    @Override public void handleMessage(Message msg) {
      mTvTimer.setText(String.valueOf(msg.what));
    }
  };
  private Handler mThreadHandler;
  private TextView mTvTimer;
  private HandlerThread mXixi;
  private List<String> mList = new ArrayList<>();
  // 或者这样:重新生成List，各个方法都同步了，所以是安全的
  //private List<String> mList = Collections.synchronizedList(new ArrayList<String>());

  @Override protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    startActivity(new Intent(this, MAActivity.class));
    Zujie zujie = getClass().getAnnotation(Zujie.class);
    String name = zujie.name();
    System.out.println("name = " + name);
    setContentView(R.layout.activity_main);
    mTvTimer = (TextView) findViewById(R.id.tv_timer);

    //new Thread(new Runnable() {
    //  @Override public void run() {
    //    mMainHandler.sendEmptyMessage(100);
    //    // Can't create handler inside thread that has not called Looper.prepare()
    //    Looper.prepare();
    //    // Run the message queue in this thread. Be sure to call
    //    Looper.loop();
    //    mThreadHandler = new MyThreadHandler();
    //  }
    //}).start();

    mXixi = new HandlerThread("xixi");
    mXixi.start();
    mThreadHandler = new MyThreadHandler(mXixi.getLooper());

    mMainHandler.postDelayed(new Runnable() {
      @Override public void run() {
        // 主线程通信子线程
        mThreadHandler.sendEmptyMessage(10);
      }
    }, 2000);

    //new Thread(new Runnable() {
    //  @Override public void run() {
    //    tryLock("1");
    //  }
    //}).start();
    //new Thread(new Runnable() {
    //  @Override public void run() {
    //    tryLock("2");
    //  }
    //}).start();

    for (int i = 0; i < 10; i++) {
      final String num = String.valueOf(i);
      new Thread(new Runnable() {
        @Override public void run() {
          ad(num);
        }
      }).start();
    }

    new Handler().postDelayed(new Runnable() {
      @Override public void run() {
        System.out.println("mList = " + mList);
      }
    }, 1000);
  }

  private synchronized void fun(String str) {
    System.out.println("fun = " + str);
  }

  private /*synchronized*/ void ad(String str) {
    mList.add(str);
  }

  /**
   * 多线程操作，加锁
   * 等同于 锁 this，如果这个对象被锁了
   * 如果两个用的同一个锁就会阻塞了
   */
  private synchronized void add(String str) {
    System.out.println("add = " + str);
    try {
      Thread.sleep(1000);
    } catch (InterruptedException e) {
      e.printStackTrace();
      mList.add(str);
    }
  }

  private final Object mLock = new Object();

  private void add2(String str) {
    System.out.println("add2 = " + str);
    synchronized (mLock) {
      try {
        Thread.sleep(10000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      mList.add(str);
    }
  }

  private final Lock mWriteLock = new ReentrantReadWriteLock().writeLock();

  /**
   * tryLock()方法是有返回值的，它表示用来尝试获取锁，如果获取成功，则返回true，如果获取失败（即锁已被其他线程获取），则返回false，
   * 也就说这个方法无论如何都会立即返回。在拿不到锁时不会一直在那等待。
   */
  private void tryLock(String str) {
    System.out.println("tryLock = " + str);
    if (mWriteLock.tryLock()) { // 尝试获取锁，如果得到返回true，如果没有，则不会阻塞
      try {
        System.out.println("拿到了锁 = " + str);
        Thread.sleep(100);
        mList.add(str);
      } catch (InterruptedException e) {
        e.printStackTrace();
      } finally {
        // 释放锁
        mWriteLock.unlock();
        System.out.println("释放锁 = " + str);
      }
    } else {
      // TODO 拿不到锁
      System.out.println("未拿到锁 = " + str);
    }
  }

  private void lock(String str) {
    mWriteLock.lock();
    System.out.println("add4 = " + str);
    try {
      Thread.sleep(100);
      mList.add(str);
    } catch (InterruptedException e) {
      e.printStackTrace();
    } finally {
      // 释放锁
      mWriteLock.unlock();
    }
  }

  @Override protected void onDestroy() {
    mXixi.quit();
    super.onDestroy();
  }

  private class MyThreadHandler extends Handler {
    public MyThreadHandler() {
    }

    public MyThreadHandler(Looper mainLooper) {
      super(mainLooper);
    }

    @Override public void handleMessage(Message msg) {
      System.out.println("msg = " + msg.what);
    }
  }
}
